package com.example.base.adapter

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.LifecycleObserver
import androidx.recyclerview.widget.RecyclerView
import com.example.base.adapter.holder.RVHolder
import com.example.base.adapter.holder.newRvHolder
import com.example.base.adapter.listener.OnItemTouchEventListener
import com.example.base.adapter.selector.Selector
import java.util.ArrayList

/**
 *  可以的话尽量使用
 *  LifecycleAdapter
 *
 *  这个没有生命周期管理
 */
open class XAdapter<T, VH : RVHolder>(protected val layoutId: Int) : RecyclerView.Adapter<VH>(),
    IAdapter<T>, LifecycleObserver {

    private var data: MutableList<T> = ArrayList()
    private var selector: Selector = Selector()
    var onItemTouchEventListener: OnItemTouchEventListener? = null

    init {
        selector.selectMode = Selector.SINGLE_MODE
    }

    /**
     * 设置onItemTouchEventListener
     * 默认是 onItemClick
     *  毕竟很多时候，不是3个都需要设置的
     */
    fun setOnItemTouchEventAction(onItemLongClick: ((view: View, position: Int) -> Boolean) ?= null,
                               onItemChildClick: ((view: View, position: Int) -> Unit)? = null,
                               onItemClick: ((view: View, position: Int) -> Unit)? = null) {
        onItemTouchEventListener = object : OnItemTouchEventListener {
            override fun onItemClick(view: View, position: Int) {
                onItemClick?.invoke(view, position)
            }

            override fun onItemLongClick(view: View, position: Int): Boolean {
                return onItemLongClick?.invoke(view, position) ?: false
            }

            override fun onItemChildClick(view: View, position: Int) {
                onItemChildClick?.invoke(view, position)
            }
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
        val itemView = LayoutInflater.from(parent.context).inflate(layoutId, parent, false)
        val rvHolder = newRvHolder<VH>(itemView)
        rvHolder.onItemTouchEventListener = this.onItemTouchEventListener
        return rvHolder
    }

    override fun getItemCount(): Int {
        return data.size
    }

    override fun onBindViewHolder(viewHolder: VH, position: Int) {
        selector.bindHolder(viewHolder, position)
        fillData(viewHolder, position, getItem(position))
    }

    open fun fillData(rvHolder: VH, position: Int, model: T?) {
    }

    override fun getItem(position: Int): T? {
        if (data.isEmpty()) {
            return null
        }
        if (position < 0 || position > data.size - 1) {
            return null
        }
        return data[position]
    }

    override fun getData(): List<T> {
        return data
    }

    /**
     * 在集合头部添加新的数据集合（下拉从服务器获取最新的数据集合，例如新浪微博加载最新的几条微博数据）
     *
     * @param data 添加数据
     */
    override fun addNewData(data: List<T>) {
        this.data.addAll(0, data)
        notifyItemRangeInserted(0, data.size)
    }

    /**
     * 在集合尾部添加更多数据集合（上拉从服务器获取更多的数据集合，例如新浪微博列表上拉加载更晚时间发布的微博数据）
     *
     * @param data 添加数据
     */
    override fun addMoreData(data: List<T>) {
        this.data.addAll(this.data.size, data)
        notifyItemRangeInserted(this.data.size, data.size)
    }

    /**
     * 设置全新的数据集合，如果传入null，则清空数据列表（第一次从服务器加载数据，或者下拉刷新当前界面数据表）
     *
     * @param data 添加数据
     */
    override fun setData(data: List<T>) {
        this.data.clear()
        this.data.addAll(data)
        notifyDataSetChanged()
    }

    /**
     * 清空数据列表
     */
    override fun clear() {
        data.clear()
        notifyDataSetChanged()
        selector.clearSelections()
    }

    /**
     * 删除指定索引数据条目
     *
     * @param position item位置
     */
    override fun removeItem(position: Int) {
        data.removeAt(position)
        selector.removed(position)
        notifyDataSetChanged()

    }

    /**
     * 删除指定数据条目
     *
     * @param model 数据模型
     */
    override fun removeItem(model: T) {
        removeItem(data.indexOf(model))
    }

    /**
     * 在指定位置添加数据条目
     *
     * @param position 位置
     * @param model    模型
     */
    override fun addItem(position: Int, model: T) {
        data.add(position, model)
        notifyItemInserted(position)
    }

    /**
     * 在集合头部添加数据条目
     *
     * @param model 模型
     */
    override fun addFirstItem(model: T) {
        addItem(0, model)
    }

    /**
     * 在集合末尾添加数据条目
     *
     * @param model 模型
     */
    override fun addLastItem(model: T) {
        addItem(data.size, model)
    }

    /**
     * 替换指定索引的数据条目
     *
     * @param position 位置
     * @param newModel 对象
     */
    override fun setItem(position: Int, newModel: T) {
        data[position] = newModel
        notifyItemChanged(position)
    }

    /**
     * 替换指定数据条目
     *
     * @param oldModel 老模型
     * @param newModel 新模型
     */
    override fun setItem(oldModel: T, newModel: T) {
        setItem(data.indexOf(oldModel), newModel)
    }

    /**
     * 移动数据条目的位置
     *
     * @param fromPosition 起始位置
     * @param toPosition   终点位置
     */
    override fun moveItem(fromPosition: Int, toPosition: Int) {
        data.add(toPosition, data.removeAt(fromPosition))
        notifyItemMoved(fromPosition, toPosition)
        selector.clearSelections()
    }

    fun getSelector(): Selector {
        return selector
    }
}